package org.budo.dubbo.protocol.http.invocation.adapter.impl;

import java.lang.reflect.Method;
import java.util.Map;

import org.budo.dubbo.protocol.http.invocation.BudoDubboRpcInvocation;
import org.budo.dubbo.protocol.http.invocation.adapter.ProtocolRequest;
import org.budo.dubbo.protocol.http.util.BudoReflectionUtil;
import org.budo.support.fastjson.Fastjson;
import org.budo.support.lang.util.ReflectUtil;

/**
 * Websocket在用的
 * 
 * @author lmw
 */
public class ProtocolRequestInvocationAdapter extends WebHttpInvocationAdapter {
    private static final ThreadLocal<Object> THREAD_LOCAL = new ThreadLocal<Object>();

    @Override
    public BudoDubboRpcInvocation adaptInvocation(ProtocolRequest protocolRequest) throws Throwable {
        ProtocolRequest cometdProtocolRequest = (ProtocolRequest) protocolRequest;
        THREAD_LOCAL.set(cometdProtocolRequest); // THREAD_LOCAL

        String interfaceNameInUrl = cometdProtocolRequest.getInterfaceName();
        String matchedInterfaceName = BudoReflectionUtil.getMatchedInterfaceNameCached(interfaceNameInUrl); // 已缓存
        String methodName = cometdProtocolRequest.getMethodName();

        Method matchedMethod = BudoReflectionUtil.getMatchedMethodCached(matchedInterfaceName, methodName); // 已缓存
        Class<?> matchedInterface = ReflectUtil.classForName(matchedInterfaceName);

        BudoDubboRpcInvocation invocation = new BudoDubboRpcInvocation();
        invocation.setInterfaceName(matchedInterfaceName);
        invocation.setMethodName(methodName);

        invocation.setParameterTypes(matchedMethod.getParameterTypes());

        String requestBody = Fastjson.toJSONString(protocolRequest.getArguments());

        Object[] args = this.argumentArray(protocolRequest, requestBody, matchedMethod, matchedInterface);
        invocation.setArguments(args);

        return invocation;
    }

    @Override
    protected Object deserializeRequestBody(ProtocolRequest request, String requestBody, Method matchedMethod, Class<?> type) {
        ProtocolRequest protocolRequest = (ProtocolRequest) THREAD_LOCAL.get(); // THREAD_LOCAL
        Map<String, Object> arguments = protocolRequest.getArguments();
        THREAD_LOCAL.remove();
        return arguments;
    }
}